package com.grf.es.transport;

import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.LongTerms;
import org.elasticsearch.search.aggregations.bucket.terms.StringTerms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.avg.AvgAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.max.MaxAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.stats.Stats;
import org.elasticsearch.search.aggregations.metrics.stats.StatsAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.sum.Sum;
import org.elasticsearch.search.aggregations.metrics.max.Max;
import org.elasticsearch.search.aggregations.metrics.valuecount.ValueCount;
import org.elasticsearch.search.aggregations.metrics.avg.Avg;
import org.elasticsearch.search.aggregations.metrics.valuecount.ValueCountAggregationBuilder;

import java.net.UnknownHostException;

/**
 * Transport 的 聚合 操作
 */
public class Aggregation {

    /**
     * 计数
     * @throws UnknownHostException
     */
    public void count() throws UnknownHostException {
        TransportClient client = Client.getClient();
        AggregationBuilder aggregationBuilder =
                AggregationBuilders.count("count").field("timestamp");
        BoolQueryBuilder q = QueryBuilders.boolQuery().must(
                QueryBuilders.rangeQuery("timestamp")
                        .from("2019-12-01", true)
                        .to("2019-12-02", true)
        );
        SearchResponse searchResponse = client.prepareSearch("test").setTypes("movie").setQuery(q)
                .addAggregation(aggregationBuilder).get();
        SearchHits hits = searchResponse.getHits();
        for (SearchHit hit : hits) {
            System.out.println(hit.getSourceAsString());
        }
        ValueCount valueCount = searchResponse.getAggregations().get("count");
        System.out.println(valueCount.getValue());
        client.close();
    }

    /**
     * 求平均值
     */
    public void avg() throws UnknownHostException {
        TransportClient client = Client.getClient();
        AvgAggregationBuilder aggregationBuilder = AggregationBuilders.avg("avg").field("rank");
        SearchResponse searchResponse = client.prepareSearch("test").setTypes("movie")
                .addAggregation(aggregationBuilder).get();
        Avg avg = searchResponse.getAggregations().get("avg");
        System.out.println(avg.getValue());
    }

    /**
     * 求最大值
     *
     * @throws UnknownHostException
     */
    public void max() throws UnknownHostException {
        TransportClient client = Client.getClient();
        MaxAggregationBuilder maxAggregationBuilder = AggregationBuilders.max("max").field("rank");
//        BoolQueryBuilder q = QueryBuilders.boolQuery().must(
//                QueryBuilders.termQuery("终结者")
//        );
        SearchResponse searchResponse = client.prepareSearch("test")
                .setTypes("movie").addAggregation(maxAggregationBuilder).get();
        Max max = searchResponse.getAggregations().get("max");
//        SearchHits hits = searchResponse.getHits();
//        System.out.println("命中" + hits.getTotalHits() + "次");
//        for (SearchHit hit : hits) {
//            System.out.println(hit.getSourceAsString());
//        }
        System.out.println("最大值" + max.getValue());
        client.close();
    }

    /**
     * 求和
     */
    public void sum() throws UnknownHostException {
        TransportClient client = Client.getClient();
        AggregationBuilder aggregationBuilder = AggregationBuilders.sum("sum")
                .field("rank");
        SearchResponse response = client.prepareSearch("test").
                addAggregation(aggregationBuilder).execute().actionGet();
        Sum sum = response.getAggregations().get("sum");
        System.out.println(response.getHits().getTotalHits());
        System.out.println(sum.getValue());
        client.close();
    }

    /**
     * 统计
     */
    public void stats() throws UnknownHostException {
        TransportClient client = Client.getClient();
        StatsAggregationBuilder aggregationBuilder = AggregationBuilders.stats("stats")
                .field("rank");
        SearchResponse searchResponse = client.prepareSearch("test").setTypes("movie")
                .addAggregation(aggregationBuilder).get();
        Stats stats = searchResponse.getAggregations().get("stats");
        System.out.println("最大值" + stats.getMax());
        System.out.println("最小值" + stats.getMin());
        System.out.println("平均值" + stats.getAvg());
        System.out.println("总和" + stats.getSum());
        System.out.println("计数" + stats.getCount());
    }

    /**
     * 桶聚合
     */
    public void subAggregation() throws UnknownHostException {
        TransportClient client = Client.getClient();
        AggregationBuilder aggregationBuilder = AggregationBuilders
                .terms("by_time").field("timestamp");
        AggregationBuilder countAggregationBuilder = AggregationBuilders
                .count("count").field("rank");
        aggregationBuilder.subAggregation(countAggregationBuilder);
        SearchResponse searchResponse = client.prepareSearch("test").setTypes("movie")
                .addAggregation(aggregationBuilder).get();
        Aggregations aggregations = searchResponse.getAggregations();
        for (org.elasticsearch.search.aggregations.Aggregation a : aggregations) {
            StringTerms longTerms = (StringTerms) a;
            for(StringTerms.Bucket bucket : longTerms.getBuckets()){
                System.out.println("时间:" + (bucket.getKeyAsString())
                + ",个数:" + ((ValueCount)bucket.getAggregations().asMap().get("count")).getValue());
            }
        }
        client.close();
    }

    /**
     * 过滤
     */
    public void filter() throws UnknownHostException {
        TransportClient client = Client.getClient();

    }

    public static void main(String[] args) throws UnknownHostException {
        Aggregation aggregation = new Aggregation();
        //aggregation.count();
        //aggregation.max();
        //aggregation.sum();
        //aggregation.stats();
        //aggregation.avg();
        aggregation.subAggregation();
    }

}
